Release 10.1A: OpenEdge Development:
Progress 4GL Handbook


Extending the sample procedure with a dynamic browse

If you start with h-CustOrderWin7.w, you can add a dynamic browse to it to illustrate some of the capabilities of this object.

To show all the OrderLines for the current Order in a browse:

  1. In the Definitions section, add these definitions:
  2. /* These variables are used just by the dynamic browse variation 
        of this trigger. */ 
      DEFINE VARIABLE hBrowse   AS HANDLE      NO-UNDO. 
      DEFINE VARIABLE hCalcCol  AS HANDLE      NO-UNDO. 
      DEFINE QUERY qOrderLine   FOR OrderLine SCROLLING. 
    

    The hBrowse variable will hold the handle of the dynamic browse you create, and hCalcCol will hold the handle of a dynamic calculated column for it. The query definition will be attached to the browse when you create it. These definitions need to be here at the top level of the procedure so that their values persist beyond the end of the trigger where they are assigned.

  3. Add this statement to the end of the initSelection internal procedure, which sets the list of OrderLine fields in the selection list:
  4. OlineFields:ADD-LAST("Price B4 Disc"). 
    

    The new entry represents a calculated column that holds the OrderLine price before the discount is applied.

  5. In the LEAVE trigger for the selection list called OlineFields, comment out all of the code.
  6. This code created dynamic fields to display an OrderLine. Now you’ll display a browse in the same place.

  7. Because you can create a browse over and over again with different lists of columns, you should first check to see if there’s already a dynamic browse and delete it:
  8. /* This block of code is the second version of the trigger, which creates 
        a dynamic browse to show the selected fields. */ 
           
      IF VALID-HANDLE(hBrowse) THEN  
        DELETE OBJECT hBrowse. 
    

  9. Add new code to create a dynamic browse. This complex statement defines the browse and its attributes:
  10. CREATE BROWSE hBrowse 
        ASSIGN FRAME = FRAME CustQuery:HANDLE 
               WIDTH = 50 
               DOWN  = 6 
               ROW   = 8 
               COL   = 82 
               ROW-MARKERS = NO 
               SENSITIVE   = TRUE 
               SEPARATORS  = TRUE 
               READ-ONLY   = FALSE 
               NO-VALIDATE = YES 
               VISIBLE     = TRUE 
               QUERY = QUERY qOrderLine:HANDLE. 
    

  11. If necessary, adjust the size and position of the browse according to the layout of your own window and Order browse.
  12. Add code that walks through the selected fields from the OlineFields selection list as the dynamic fill-in code does:
  13. cFields = OLineFields:SCREEN-VALUE. 
      DO iField = 1 TO NUM-ENTRIES(cFields): 
         cField = ENTRY(iField, cFields). 
    

  14. If the selected field is the calculated field, you must add a calculated column to the browse to display it:
  15. IF cField = "Price B4 Disc" THEN 
              hCalcCol = hBrowse:ADD-CALC-COLUMN 
              ("Decimal",          /* Data type */ 
              ">,>>>,>>9.99",      /* Format */ 
              "0",                 /* Initial value */ 
              "Price B4 Disc").    /* column label */ 
    

  16. Otherwise, add a column like the selected field in the OrderLine table:
  17.   ELSE hBrowse:ADD-LIKE-COLUMN("OrderLine." + cField). 
      END.     /* END DO iField… */ 
    

  18. Add this ROW-DISPLAY trigger, which executes each time a row is displayed in the browse:
  19. ON ROW-DISPLAY OF hBrowse 
         PERSISTENT RUN calcPriceB4Disc. 
    

    Because the code in the trigger block for LEAVE of OlineFields goes out of scope as soon as the trigger block ends, you must put the code for this nested trigger definition in a separate procedure, and use the special syntax PERSISTENT RUN calcPriceB4Disc to make Progress keep track of what to run when the ROW-DISPLAY event fires.

  20. Add this LEAVE trigger to open the OrderLine query from the Definitions section:
  21. OPEN QUERY qOrderLine FOR EACH OrderLine 
         WHERE OrderLine.OrderNum = Order.OrderNum. 
    

    You attached this query to the browse in the CREATE BROWSE statement.

  22. Add this code for the calcPriceB4Disc procedure:
  23. /*--------------------------------------------------------------------- 
      Procedure:  calcPriceB4Disc 
      Purpose:    Calculates the value of the calculated column PriceB4Disc.  
      Parameters:  <none> 
    ---------------------------------------------------------------------*/ 
    IF VALID-HANDLE(hCalcCol) THEN 
             hCalcCol:SCREEN-VALUE = STRING(OrderLine.Price * 
    OrderLine.Qty). 
    END PROCEDURE. 
    

    A trigger such as this should always check first that its column handle is valid in case it is fired once before the column is created. In this case, the column is optional, so it must always check first to see if it’s there.

  24. In the VALUE-CHANGED trigger for the OrderBrowse, comment out the existing code that blanks out the dynamic fill-ins and replace it with a statement that re-opens the OrderLine query:
  25. /* This is the second version of this trigger, for the dynamic browse 
         example. */ 
      OPEN QUERY qOrderLine FOR EACH OrderLine WHERE OrderLine.OrderNum 
          = Order.OrderNum. 
    

    This code refreshes the OrderLine browse each time an Order is selected.

  26. Add this statement to each of the four navigation button triggers to apply the Order browse’s VALUE-CHANGED trigger:
  27. DO: 
      GET NEXT CustQuery. 
      IF AVAILABLE Customer THEN  
       DISPLAY Customer.CustNum Customer.Name Customer.Address Customer.City  
               Customer.State  
          WITH FRAME CustQuery IN WINDOW CustWin. 
      {&OPEN-BROWSERS-IN-QUERY-CustQuery} 
      APPLY "VALUE-CHANGED" TO BROWSE OrderBrowse. 
    END. 
    

    The query opens when a new Customer is selected and its Orders first displayed.

  28. Run h-CustOrderWin7.w. You can select some OrderLine fields along with the calculated field and see the results of your work:

Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095